From c897cb3bac0a262a446dd8591e6be6bb8bb33861 Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Tue, 3 Aug 2004 10:55:54 +0000 Subject: [PATCH] bitkeeper revision 1.1108.33.42 (410f6f3aRsLN-XTc0i2kCrGt2plvhw) More NMI-handling cleanups. Users now have an option of what to do with an error NMI by specifying 'nmi=xxx' on Xen's cmdline. 'nmi=dom0' -> Tell DOM0 about it (DOM0 currently ignores it). 'nmi=ignore' -> ignore it 'nmi=fatal' -> print a diagnostic and then hang. --- README.CD | 11 ++-- docs/HOWTOs/Xen-HOWTO | 11 ++-- docs/user.tex | 75 +++++++++++----------- xen/arch/x86/traps.c | 39 +++++++---- xen/arch/x86/x86_32/entry.S | 40 +++++++++--- xen/common/kernel.c | 12 ++++ xen/include/hypervisor-ifs/hypervisor-if.h | 4 +- xen/include/xen/softirq.h | 22 +++---- 8 files changed, 135 insertions(+), 79 deletions(-) diff --git a/README.CD b/README.CD index a0e47f3183..fcf94be18f 100644 --- a/README.CD +++ b/README.CD @@ -277,10 +277,6 @@ that may be able to help diagnose problems: noht Disable Hyperthreading. - ifname=ethXX Select which Ethernet interface to use. - - ifname=dummy Don't use any network interface. - com1=,DPS[,,] com2=,DPS[,,] Xen supports up to two 16550-compatible serial ports. @@ -317,6 +313,13 @@ that may be able to help diagnose problems: omitting the character, enables auto-switching. [NB. Default for this option is 'a'] + nmi= + Specify what to do with an NMI parity or I/O error. + 'nmi=fatal': Xen prints a diagnostic and then hangs. + 'nmi=dom0': Inform DOM0 of the NMI. + 'nmi=ignore': Ignore the NMI. + [NB. Default is 'dom0' ('fatal' for debug builds).] + dom0_mem=xxx Set the initial amount of memory for domain0. pdb=xxx Enable the pervasive debugger. See docs/pdb.txt diff --git a/docs/HOWTOs/Xen-HOWTO b/docs/HOWTOs/Xen-HOWTO index eee9251577..272670baa1 100644 --- a/docs/HOWTOs/Xen-HOWTO +++ b/docs/HOWTOs/Xen-HOWTO @@ -223,10 +223,6 @@ The following is a list of command line arguments to pass to Xen: noht Disable Hyperthreading. - ifname=ethXX Select which Ethernet interface to use. - - ifname=dummy Don't use any network interface. - com1=,DPS[,,] com2=,DPS[,,] Xen supports up to two 16550-compatible serial ports. @@ -263,6 +259,13 @@ The following is a list of command line arguments to pass to Xen: omitting the character, enables auto-switching. [NB. Default for this option is 'a'] + nmi= + Specify what to do with an NMI parity or I/O error. + 'nmi=fatal': Xen prints a diagnostic and then hangs. + 'nmi=dom0': Inform DOM0 of the NMI. + 'nmi=ignore': Ignore the NMI. + [NB. Default is 'dom0' ('fatal' for debug builds).] + dom0_mem=xxx Set the maximum amount of memory for domain0. tbuf_size=xxx Set the size of the per-cpu trace buffers, in pages diff --git a/docs/user.tex b/docs/user.tex index 10c3ed3821..90fbbf4fae 100644 --- a/docs/user.tex +++ b/docs/user.tex @@ -777,43 +777,43 @@ The available commands are as follows: \begin{description} \item[Atropos] One of the CPU schedulers provided by Xen. Atropos provides domains with absolute shares - of the CPU, with timeliness guarantees and a - mechanism for sharing out ``slack time''. + of the CPU, with timeliness guarantees and a + mechanism for sharing out ``slack time''. \item[BVT] The BVT scheduler is used to give propotional fair shares of the CPU to domains. \item[Exokernel] A minimal piece of privileged code, similar to a {\bf microkernel} but providing a more - `hardware-like' interface to the tasks it - manages. This is similar to a paravirtualising - VMM like {\bf Xen} but was designed as a new - operating system structure, rather than - specifically to run multiple conventional OSs. + `hardware-like' interface to the tasks it + manages. This is similar to a paravirtualising + VMM like {\bf Xen} but was designed as a new + operating system structure, rather than + specifically to run multiple conventional OSs. \item[FBVT] A derivative of the { \bf BVT } scheduler that aims to give better fairness performance to IO - intensive domains in competition with CPU - intensive domains. + intensive domains in competition with CPU + intensive domains. \item[Domain] A domain is the execution context that contains a running { \bf virtual machine }. - The relationship between virtual machines - and domains on Xen is similar to that between - programs and processes in an operating - system: a virtual machine is a persistent - entity that resides on disk (somewhat like - a program). When it is loaded for execution, - it runs in a domain. Each domain has a - { \bf domain ID }. + The relationship between virtual machines + and domains on Xen is similar to that between + programs and processes in an operating + system: a virtual machine is a persistent + entity that resides on disk (somewhat like + a program). When it is loaded for execution, + it runs in a domain. Each domain has a + { \bf domain ID }. \item[Domain 0] The first domain to be started on a Xen machine. Domain 0 is responsible for managing - the system. + the system. \item[Domain ID] A unique identifier for a { \bf domain }, analagous to a process ID in an operating - system. Apart from domain + system. Apart from domain \item[Full virtualisation] An approach to virtualisation which requires no modifications to the hosted @@ -822,18 +822,18 @@ The available commands are as follows: \item[Hypervisor] An alternative term for { \bf VMM }, used because it means ``beyond supervisor'', - since it is responsible for managing multiple - ``supervisor'' kernels. + since it is responsible for managing multiple + ``supervisor'' kernels. \item[Microkernel] A small base of code running at the highest hardware privilege level. A microkernel is - responsible for sharing CPU and memory (and - sometimes other devices) between less - privileged tasks running on the system. - This is similar to a VMM, particularly a - {\bf paravirtualising} VMM but typically - addressing a different problem space and - providing different kind of interface. + responsible for sharing CPU and memory (and + sometimes other devices) between less + privileged tasks running on the system. + This is similar to a VMM, particularly a + {\bf paravirtualising} VMM but typically + addressing a different problem space and + providing different kind of interface. \item[NetBSD/Xen] A port of NetBSD to the Xen architecture. @@ -853,12 +853,12 @@ The available commands are as follows: \item[VMM] Virtual Machine Monitor - the software that allows multiple virtual machines to be - multiplexed on a single physical machine. + multiplexed on a single physical machine. \item[Xen] Xen is a paravirtualising virtual machine monitor, developed primarily by the - Systems Research Group at the University - of Cambridge Computer Laboratory. + Systems Research Group at the University + of Cambridge Computer Laboratory. \item[XenLinux] Official name for the port of the Linux kernel that runs on Xen. @@ -1140,12 +1140,6 @@ editting \path{grub.conf}. {\bf noht } \\ Disable Hyperthreading. \\ -{\bf ifname=ethXX }\\ - Select which Ethernet interface to use. \\ - -{\bf ifname=dummy } \\ - Don't use any network interface. \\ - {\bf com1=$<$baud$>$,DPS[,$<$io\_base$>$,$<$irq$>$] \\ com2=$<$baud$>$,DPS[,$<$io\_base$>$,$<$irq$>$] } \\ Xen supports up to two 16550-compatible serial ports. @@ -1184,6 +1178,13 @@ editting \path{grub.conf}. omitting the character, enables auto-switching. [NB. Default for this option is 'a'] \\ +{\bf nmi=xxx } \\ + Specify what to do with an NMI parity or I/O error. \\ + 'nmi=fatal': Xen prints a diagnostic and then hangs. \\ + 'nmi=dom0': Inform DOM0 of the NMI. \\ + 'nmi=ignore': Ignore the NMI. \\ + [NB. Default is 'dom0' ('fatal' for debug builds).] \\ + {\bf dom0\_mem=xxx } \\ Set the maximum amount of memory for domain0. \\ diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index dbc91d5114..3570781bf2 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -36,9 +36,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -52,6 +54,8 @@ #include #include +extern char opt_nmi[]; + struct guest_trap_bounce guest_trap_bounce[NR_CPUS] = { { 0 } }; #if defined(__i386__) @@ -472,16 +476,11 @@ asmlinkage void do_general_protection(struct pt_regs *regs, long error_code) die("general protection fault", regs, error_code); } -asmlinkage void mem_parity_error(unsigned char reason, struct pt_regs *regs) +asmlinkage void mem_parity_error(struct pt_regs *regs) { console_force_unlock(); - printk("\n\nNMI received. Dazed and confused, but trying to continue\n"); - printk("You probably have a hardware problem with your RAM chips\n"); - - /* Clear and disable the memory parity error line. */ - reason = (reason & 0xf) | 4; - outb(reason, 0x61); + printk("\n\n"); show_registers(regs); @@ -497,14 +496,11 @@ asmlinkage void mem_parity_error(unsigned char reason, struct pt_regs *regs) for ( ; ; ) ; } -asmlinkage void io_check_error(unsigned char reason, struct pt_regs *regs) +asmlinkage void io_check_error(struct pt_regs *regs) { console_force_unlock(); - printk("\n\nNMI: IOCK error (debug interrupt?)\n"); - - reason = (reason & 0xf) | 8; - outb(reason, 0x61); + printk("\n\n"); show_registers(regs); @@ -539,6 +535,23 @@ asmlinkage void do_nmi(struct pt_regs * regs, unsigned long reason) unknown_nmi_error((unsigned char)(reason&0xff), regs); } +unsigned long nmi_softirq_reason; +static void nmi_softirq(void) +{ + struct domain *d = find_domain_by_id(0); + + if ( d == NULL ) + return; + + if ( test_and_clear_bit(0, &nmi_softirq_reason) ) + send_guest_virq(d, VIRQ_PARITY_ERR); + + if ( test_and_clear_bit(1, &nmi_softirq_reason) ) + send_guest_virq(d, VIRQ_IO_ERR); + + put_domain(d); +} + asmlinkage void math_state_restore(struct pt_regs *regs, long error_code) { /* Prevent recursion. */ @@ -751,6 +764,8 @@ void __init trap_init(void) extern void cpu_init(void); cpu_init(); } + + open_softirq(NMI_SOFTIRQ, nmi_softirq); } diff --git a/xen/arch/x86/x86_32/entry.S b/xen/arch/x86/x86_32/entry.S index 3308969877..fbd33eb73b 100644 --- a/xen/arch/x86/x86_32/entry.S +++ b/xen/arch/x86/x86_32/entry.S @@ -58,6 +58,7 @@ #include #include +#include #include EBX = 0x00 @@ -598,8 +599,7 @@ ENTRY(nmi) pushl %eax SAVE_ALL_NOSEGREGS - # Check for hardware problems. These are always fatal so we can - # reload DS and ES when handling them. + # Check for hardware problems. inb $0x61,%al testb $0x80,%al jne nmi_parity_err @@ -656,25 +656,45 @@ nmi_badseg: addl $20,%esp iret -nmi_parity_err: - movl $(__HYPERVISOR_DS),%edx +nmi_parity_err: + # Clear and disable the parity-error line + andb $0xf,%al + orb $0x4,%al + outb %al,$0x61 + cmpb $'i',%ss:SYMBOL_NAME(opt_nmi) # nmi=ignore + je nmi_badseg + bts $0,%ss:SYMBOL_NAME(nmi_softirq_reason) + bts $NMI_SOFTIRQ,%ss:SYMBOL_NAME(irq_stat) + cmpb $'d',%ss:SYMBOL_NAME(opt_nmi) # nmi=dom0 + je nmi_badseg + movl $(__HYPERVISOR_DS),%edx # nmi=fatal movl %edx,%ds movl %edx,%es movl %esp,%edx push %edx - push %eax call SYMBOL_NAME(mem_parity_error) - ud2 - + addl $4,%esp + jmp ret_from_intr + nmi_io_err: - movl $(__HYPERVISOR_DS),%edx + # Clear and disable the I/O-error line + andb $0xf,%al + orb $0x8,%al + outb %al,$0x61 + cmpb $'i',%ss:SYMBOL_NAME(opt_nmi) # nmi=ignore + je nmi_badseg + bts $1,%ss:SYMBOL_NAME(nmi_softirq_reason) + bts $NMI_SOFTIRQ,%ss:SYMBOL_NAME(irq_stat) + cmpb $'d',%ss:SYMBOL_NAME(opt_nmi) # nmi=dom0 + je nmi_badseg + movl $(__HYPERVISOR_DS),%edx # nmi=fatal movl %edx,%ds movl %edx,%es movl %esp,%edx push %edx - push %eax call SYMBOL_NAME(io_check_error) - ud2 + addl $4,%esp + jmp ret_from_intr .data ENTRY(hypercall_table) diff --git a/xen/common/kernel.c b/xen/common/kernel.c index dd71dc092b..9d6d6e92f7 100644 --- a/xen/common/kernel.c +++ b/xen/common/kernel.c @@ -80,6 +80,17 @@ char opt_leveltrigger[30] = "", opt_edgetrigger[30] = ""; * pfn_info table and allocation bitmap. */ unsigned int opt_xenheap_megabytes = XENHEAP_DEFAULT_MB; +/* + * opt_nmi: one of 'ignore', 'dom0', or 'fatal'. + * fatal: Xen prints diagnostic message and then hangs. + * dom0: The NMI is virtualised to DOM0. + * ignore: The NMI error is cleared and ignored. + */ +#ifdef NDEBUG +char opt_nmi[10] = "dom0"; +#else +char opt_nmi[10] = "fatal"; +#endif static struct { unsigned char *name; @@ -104,6 +115,7 @@ static struct { { "leveltrigger", OPT_STR, &opt_leveltrigger }, { "edgetrigger", OPT_STR, &opt_edgetrigger }, { "xenheap_megabytes", OPT_UINT, &opt_xenheap_megabytes }, + { "nmi", OPT_STR, &opt_nmi }, { NULL, 0, NULL } }; diff --git a/xen/include/hypervisor-ifs/hypervisor-if.h b/xen/include/hypervisor-ifs/hypervisor-if.h index b6231e5ec5..724213acae 100644 --- a/xen/include/hypervisor-ifs/hypervisor-if.h +++ b/xen/include/hypervisor-ifs/hypervisor-if.h @@ -65,7 +65,9 @@ #define VIRQ_DEBUG 2 /* Request guest to dump debug info. */ #define VIRQ_CONSOLE 3 /* (DOM0) bytes received on emergency console. */ #define VIRQ_DOM_EXC 4 /* (DOM0) Exceptional event for some domain. */ -#define NR_VIRQS 5 +#define VIRQ_PARITY_ERR 5 /* (DOM0) NMI parity error. */ +#define VIRQ_IO_ERR 6 /* (DOM0) NMI I/O error. */ +#define NR_VIRQS 7 /* * MMU-UPDATE REQUESTS diff --git a/xen/include/xen/softirq.h b/xen/include/xen/softirq.h index 8e45dadf18..3cb570a247 100644 --- a/xen/include/xen/softirq.h +++ b/xen/include/xen/softirq.h @@ -1,23 +1,21 @@ #ifndef __XEN_SOFTIRQ_H__ #define __XEN_SOFTIRQ_H__ +#define AC_TIMER_SOFTIRQ 0 +#define NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ 1 +#define DEBUGGER_SOFTIRQ 2 +#define NMI_SOFTIRQ 3 +#define SCHEDULE_SOFTIRQ 4 +#define NR_SOFTIRQS 5 + +#ifndef __ASSEMBLY__ + #include #include #include #include #include -enum -{ - AC_TIMER_SOFTIRQ=0, - NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ, -#ifdef XEN_DEBUGGER - DEBUGGER_SOFTIRQ, -#endif - SCHEDULE_SOFTIRQ, /* NB. This must come last or do_softirq() will break! */ - NR_SOFTIRQS -}; - typedef void (*softirq_handler)(void); asmlinkage void do_softirq(void); @@ -34,4 +32,6 @@ static inline void raise_softirq(unsigned int nr) set_bit(nr, &softirq_pending(smp_processor_id())); } +#endif /* __ASSEMBLY__ */ + #endif /* __XEN_SOFTIRQ_H__ */ -- 2.30.2